package com.soyotec.algorithm.algorithm;


import com.soyotec.algorithm.problem.Problem;
import com.soyotec.algorithm.solution.ValueWrapSolution;

import java.util.List;

/**
 * 算法抽象类
 */
public abstract class AbstractOPTAlgorithmPlugin implements OPTAlgorithmPlugin<List<ValueWrapSolution>> {
    private Problem<ValueWrapSolution> problem;

    private List<ValueWrapSolution> population = null;

    /**
     * 算法执行方法
     * 1 创建评价初始设计点集合
     * 2 计算评估设计点集
     * 3 初始化算法进度
     * 4 判断算法是否已达停止条件
     * 5 创建后代评估设计点集
     * 6 计算评估设计点集
     * 7 更新结果解集
     * 8 更新算法进度
     */
    @Override
    public void run() {
        this.population = this.createInitialPopulation();
        this.population = this.evaluatePopulation(getPopulation());
        this.initProgress();

        while (!this.isStoppingConditionReached()) {
            List<ValueWrapSolution> offspringPopulation = this.reproduction();
            offspringPopulation = this.evaluatePopulation(offspringPopulation);
            this.population = this.replacement(getPopulation(), offspringPopulation);
            this.updateProgress();

        }
    }

    /**
     * 创建初始设计点集
     *
     * @return 初始设计点集
     */
    protected abstract List<ValueWrapSolution> createInitialPopulation();

    /**
     * 设计点集计算方法
     *
     * @param population 需要计算的设计点集
     * @return 设计点集结算结果
     */
    List<ValueWrapSolution> evaluatePopulation(List<ValueWrapSolution> population) {
        problem.evaluate(population);
        return population;
    }

    /**
     * 初始化算法进度
     */
    protected abstract void initProgress();

    /**
     * 更新算法进度
     */
    protected abstract void updateProgress();

    /**
     * 算法是否达到停止条件
     *
     * @return true：算法达到停止条件；false：算法没达到停止条件
     */
    protected abstract boolean isStoppingConditionReached();

    /**
     * 创建后代设计点集
     *
     * @return 后代设计点集
     */
    protected abstract List<ValueWrapSolution> reproduction();

    /**
     * 更新结果设计点集
     *
     * @param population          结果设计点集
     * @param offspringPopulation 计算完的设计点集
     * @return 新的结果设计点集
     */
    protected abstract List<ValueWrapSolution> replacement(
            List<ValueWrapSolution> population, List<ValueWrapSolution> offspringPopulation);

    /**
     * 返回最优设计点集
     *
     * @return 最优设计点集
     */
    @Override
    public List<ValueWrapSolution> getResult() {
        return population;
    }

    /**
     * 获取问题
     *
     * @return 问题
     */
    public Problem getProblem() {
        return problem;
    }

    /**
     * 设置问题
     *
     * @param problem 问题
     */
    public void setProblem(Problem problem) {
        this.problem = problem;
    }

    /**
     * 获取种群
     *
     * @return 种群
     */
    public List<ValueWrapSolution> getPopulation() {
        return population;
    }

    /**
     * 设置种群
     *
     * @param population 种群
     */
    public void setPopulation(List<ValueWrapSolution> population) {
        this.population = population;
    }
}
